package com.jeecg.modules.jmreport.config;

import com.alibaba.fastjson.JSONObject;
import com.yiidata.intergration.common.exception.RRException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import static com.yiidata.intergration.common.utils.Constant.AUTH_TOKEN;

/**
 * 自定义积木报表鉴权(如果不进行自定义，则所有请求不做权限控制)
 * 1.自定义获取登录token
 * 2.自定义获取登录用户
 */
@Slf4j
@Component
public class JimuReportTokenService implements JmReportTokenServiceI {



    @Autowired
    JwtUtils jwtUtils;

    /**
     * 通过请求获取Token
     * @param request
     * @return
     */
    @Override
    public String getToken(HttpServletRequest request) {
        //获取请求token
        String token = getRequestToken(request);
        if(StringUtils.isBlank(token)){
            throw new RRException("无认证 " + AUTH_TOKEN + " 信息，请登录", org.springframework.http.HttpStatus.UNAUTHORIZED.value());
        }
        Claims claims = null;
        try {
            claims = jwtUtils.getClaimByToken(token);
        } catch (ExpiredJwtException e) {
            log.warn(AUTH_TOKEN + " 失效，请重新登录", e);
            throw new RRException(AUTH_TOKEN + " 失效，请重新登录", org.springframework.http.HttpStatus.UNAUTHORIZED.value());
        }
        if(claims == null) {
            throw new RRException(AUTH_TOKEN + " 失效，请重新登录", org.springframework.http.HttpStatus.UNAUTHORIZED.value());
        }

        // 登录过期
        final String subject = claims.getSubject();
        return subject;
    }

    /**
     * 通过Token获取登录人用户名
     * @param token
     * @return
     */
    @Override
    public String getUsername(String token) {
        try {
            final JSONObject jsonObject = JSONObject.parseObject(token);
            return jsonObject.getString("name");
        } catch (Exception e) {
            log.error("Token 校验不通过，异常的用户。", e);
        }
        return null;
    }

    /**
     * Token校验
     * @param token
     * @return
     */
    @Override
    public Boolean verifyToken(String token) {
        try {
            final JSONObject jsonObject = JSONObject.parseObject(token);
            String tokenStr = jsonObject.getString("token");
            return StringUtils.isNotBlank(tokenStr);
        } catch (Exception e) {
            log.error("Token 校验不通过，异常的用户。", e);
        }
        return false;
    }

    /**
     *  自定义请求头
     * @return
     */
    @Override
    public HttpHeaders customApiHeader() {
        HttpHeaders header = new HttpHeaders();
        return header;
    }


    /**
     * 获取请求的token
     */
    public static String getRequestToken(HttpServletRequest httpRequest){
        //从header中获取token
        String token = httpRequest.getHeader(AUTH_TOKEN);
        if(StringUtils.isBlank(token)){
            final Cookie[] cookies = httpRequest.getCookies();
            if(cookies != null) {
                for (Cookie cookie : cookies) {
                    if (AUTH_TOKEN.equalsIgnoreCase(cookie.getName())) {
                        token = cookie.getValue();
                        break;
                    }
                }
            }
        }

        //如果header中不存在token，则从参数中获取token
        if(StringUtils.isBlank(token)){
            token = httpRequest.getParameter(AUTH_TOKEN);
        }

        // OAuth2 认证，是以 Bearer 为前缀
        if(StringUtils.isNotBlank(token) && token.startsWith("Bearer ")) {
            return StringUtils.trimToNull(token.substring(7));
        }
        return token;
    }
}